#pragma once 
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"
using path_t = std::function<void(const Request&,Response&)>;
class HttpServer
{
private:
    bool CheckSafe(const string& path){
        return _HaT.count(path);
    }
     void HandlerRequest(SockPtr ptr,InetAddr client){
        LOG(LogLevel::INFO) << "recv from client: " << client.NetAddr();
        //接受消息
        string inbuffer;
        ptr->Recv(&inbuffer);
        LOG(LogLevel::INFO) << "接受到一个请求\n" << inbuffer;
        Request req;
        if(!req.Deserialization(inbuffer)) return;
        req.Print();
        //构建Response
        req.CheckArgs();
        Response rsp;
        //序列化
        if (req.IsHasArg()){
            if (CheckSafe(req.Path()))
                _HaT[req.Path()](req,rsp);
            else 
                rsp.Build(req);
        }
        else {
            rsp.Build(req);
        }
        rsp.Print();
        string ret;
        rsp.Serialization(&ret);
        //返回
        // //直接构建一个简易版的应答，注意下面的html文件内容要规范，标签当中不能有空格
        //     std::string _reqline = "http/1.1 200 OK\r\n";
        //     std::string bankline = "\r\n";
        //     std::string body = "<!DOCTYPE html>\
        //                             <html lang=\"zh-CN\">\
        //                                           <head>\
        //                                           <meta charset=\"UTF-8\">\
        //                                           <meta name=\"viewport\" conteny=t\"width=device-width,initial-scale=1.0\">\
        //                                           <title>Hello World</title>\
        //                                           </head>\
        //                                           <body>\
        //                                           <h1>Hello,World!</h1></body></html>";
        //     std::string rep = _reqline + bankline + body;                                                
        ptr->Send(ret);        
    }
public:
    HttpServer(uint16_t port)
        :_tsvr(std::make_shared<TcpServer>(port))
    {   
        _tsvr->Build();
    }
    void InsertPath(const string& path,path_t f){
        _HaT[path] = f;
    }
    void Init(){
        _tsvr->Insert([this](SockPtr ptr,InetAddr client){
            this->HandlerRequest(ptr,client);
        });
    }
    void Start(){
        _tsvr->Loop();
    }
private:
    std::shared_ptr<TcpServer> _tsvr;
    unordered_map<string,path_t> _HaT;
};